<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Mod上下文API参考 :: 梅尔沃放置指南</title>
    <meta name="generator" content="Antora 3.1.4">
    <link rel="stylesheet" href="../../../_/css/site.css">
  </head>
  <body class="article">
<header class="header">
  <nav class="navbar">
    <div class="navbar-brand">
      <a class="navbar-item" href="../../..">梅尔沃放置指南</a>
      <button class="navbar-burger" data-target="topbar-nav">
        <span></span>
        <span></span>
        <span></span>
      </button>
    </div>
    <div id="topbar-nav" class="navbar-menu">
      <div class="navbar-end">
        <a class="navbar-item" href="#">Home</a>
        <div class="navbar-item has-dropdown is-hoverable">
          <a class="navbar-link" href="#">Products</a>
          <div class="navbar-dropdown">
            <a class="navbar-item" href="#">Product A</a>
            <a class="navbar-item" href="#">Product B</a>
            <a class="navbar-item" href="#">Product C</a>
          </div>
        </div>
        <div class="navbar-item has-dropdown is-hoverable">
          <a class="navbar-link" href="#">Services</a>
          <div class="navbar-dropdown">
            <a class="navbar-item" href="#">Service A</a>
            <a class="navbar-item" href="#">Service B</a>
            <a class="navbar-item" href="#">Service C</a>
          </div>
        </div>
        <div class="navbar-item">
          <span class="control">
            <a class="button is-primary" href="#">Download</a>
          </span>
        </div>
      </div>
    </div>
  </nav>
</header>
<div class="body">
<div class="nav-container" data-component="melvor" data-version="1.0.0">
  <aside class="nav">
    <div class="panels">
<div class="nav-panel-menu is-active" data-panel="menu">
  <nav class="nav-menu">
    <h3 class="title"><a href="../index.html">梅尔沃放置</a></h3>
<ul class="nav-list">
  <li class="nav-item" data-depth="0">
<ul class="nav-list">
  <li class="nav-item" data-depth="1">
    <button class="nav-item-toggle"></button>
    <a class="nav-link" href="../战斗/index.html">战斗(no)</a>
<ul class="nav-list">
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../战斗/攻击.html">攻击(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../战斗/力量.html">力量(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../战斗/防御.html">防御(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../战斗/生命值.html">生命值(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../战斗/远程.html">远程(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../战斗/魔法.html">魔法(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../战斗/祝祭.html">祝祭(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../战斗/屠杀者.html">屠杀者(no)</a>
  </li>
</ul>
  </li>
  <li class="nav-item" data-depth="1">
    <button class="nav-item-toggle"></button>
    <span class="nav-text">非战斗(ing)</span>
<ul class="nav-list">
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/伐木.html">伐木(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/钓鱼.html">钓鱼(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/生火.html">生火(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/烹饪.html">烹饪(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/采矿.html">采矿(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/锻造.html">锻造(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/扒窃.html">扒窃(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/弓匠.html">弓匠(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/制造.html">制造(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/符文锻造.html">符文锻造(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/草药学.html">草药学(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/灵巧.html">灵巧(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/召唤.html">召唤(ing)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/星象学.html">星象学(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/生活类魔法.html">生活类魔法(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/制图学.html">制图学(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/考古学.html">考古学(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/农务.html">农务(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../非战斗/城镇.html">城镇(no)</a>
  </li>
</ul>
  </li>
  <li class="nav-item" data-depth="1">
    <button class="nav-item-toggle"></button>
    <span class="nav-text">练级(no)</span>
<ul class="nav-list">
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/伐木.html">伐木(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/钓鱼.html">钓鱼(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/生火.html">生火(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/烹饪.html">烹饪(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/采矿.html">采矿(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/锻造.html">锻造(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/扒窃.html">扒窃(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/弓匠.html">弓匠(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/制造.html">制造(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/符文锻造.html">符文锻造(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/草药学.html">草药学(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/灵巧.html">灵巧(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/召唤-练级.html">召唤(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/星象学.html">星象学(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/生活类魔法.html">生活类魔法(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/制图学.html">制图学(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/考古学.html">考古学(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/农务.html">农务(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../练级/城镇.html">城镇(no)</a>
  </li>
</ul>
  </li>
  <li class="nav-item" data-depth="1">
    <button class="nav-item-toggle"></button>
    <span class="nav-text">其它(no)</span>
<ul class="nav-list">
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../其它/新手指南.html">新手指南(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../其它/指南.html">指南(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../其它/仓库.html">仓库(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../其它/战斗.html">战斗(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../其它/专精.html">专精(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../其它/赚钱.html">赚钱(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../其它/商店.html">商店(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../其它/菜单.html">菜单(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../其它/宠物.html">宠物(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../其它/哥布林突袭.html">哥布林突袭(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../其它/版本信息.html">版本信息(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../其它/使徒的王座DLC.html">使徒的王座DLC(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../其它/探索地图集DLC.html">探索地图集DLC(no)</a>
  </li>
</ul>
  </li>
  <li class="nav-item" data-depth="1">
    <button class="nav-item-toggle"></button>
    <span class="nav-text">参考表格(no)</span>
<ul class="nav-list">
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../参考表格/道具.html">道具(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../参考表格/装备.html">装备(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../参考表格/经验表格.html">经验表格(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../参考表格/道具升级.html">道具升级(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../参考表格/战斗区域.html">战斗区域(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../参考表格/屠杀者区域.html">屠杀者区域(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../参考表格/副本.html">副本(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../参考表格/宝箱战利品表格.html">宝箱战利品表格(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../参考表格/怪物.html">怪物(no)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../参考表格/怪物掉落表格.html">怪物掉落表格(no)</a>
  </li>
</ul>
  </li>
  <li class="nav-item" data-depth="1">
    <button class="nav-item-toggle"></button>
    <span class="nav-text">指南(ing)</span>
<ul class="nav-list">
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../指南/战斗-练级.html">战斗-练级(ing)</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../指南/熔岩洞窟-指南.html">熔岩洞窟-指南</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="../指南/冒险模式-指南.html">冒险模式-指南</a>
  </li>
</ul>
  </li>
  <li class="nav-item" data-depth="1">
    <button class="nav-item-toggle"></button>
    <a class="nav-link" href="index.html">Mod开发</a>
<ul class="nav-list">
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="入门指南.html">入门指南</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="创作工具包.html">创作工具包</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="从脚本和扩展迁移.html">从脚本和扩展迁移</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="基础指南.html">基础指南</a>
  </li>
  <li class="nav-item is-current-page" data-depth="2">
    <a class="nav-link" href="Mod上下文API参考.html">Mod上下文API参考</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="侧边栏API参考.html">侧边栏API参考</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="使用PetiteVue创建可复用组件.html">使用PetiteVue创建可复用组件</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="启用Steam客户端的DevTools.html">启用Steam客户端的DevTools</a>
  </li>
  <li class="nav-item" data-depth="2">
    <a class="nav-link" href="游戏内功能参考.html">游戏内功能参考</a>
  </li>
</ul>
  </li>
  <li class="nav-item" data-depth="1">
    <button class="nav-item-toggle"></button>
    <span class="nav-text">工具</span>
<ul class="nav-list">
  <li class="nav-item" data-depth="2">
    <span class="nav-text"><a href="https://consolelog.gitee.io/caniidle/?language=%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87" target="_blank" rel="noopener">我能挂机吗</a></span>
  </li>
</ul>
  </li>
</ul>
  </li>
</ul>
  </nav>
</div>
<div class="nav-panel-explore" data-panel="explore">
  <div class="context">
    <span class="title">梅尔沃放置</span>
    <span class="version">1.0.0</span>
  </div>
  <ul class="components">
    <li class="component is-current">
      <a class="title" href="../index.html">梅尔沃放置</a>
      <ul class="versions">
        <li class="version is-current is-latest">
          <a href="../index.html">1.0.0</a>
        </li>
      </ul>
    </li>
  </ul>
</div>
    </div>
  </aside>
</div>
<main class="article">
<div class="toolbar" role="navigation">
<button class="nav-toggle"></button>
  <a href="../index.html" class="home-link"></a>
<nav class="breadcrumbs" aria-label="breadcrumbs">
  <ul>
    <li><a href="../index.html">梅尔沃放置</a></li>
    <li><a href="index.html">Mod开发</a></li>
    <li><a href="Mod上下文API参考.html">Mod上下文API参考</a></li>
  </ul>
</nav>
<div class="edit-this-page"><a href="file:///D:/src/game/melvor_idle_wiki/melvor/modules/ROOT/pages/mod/Mod上下文API参考.adoc">Edit this Page</a></div>
</div>
  <div class="content">
<aside class="toc sidebar" data-title="目录" data-levels="3">
  <div class="toc-menu"></div>
</aside>
<article class="doc">
<h1 class="page">Mod上下文API参考</h1>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p><a href="https://wiki.melvoridle.com/w/Mod_Creation/Mod_Context_API_Reference" target="_target">原文地址</a></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_访问_mod_上下文对象"><a class="anchor" href="#_访问_mod_上下文对象"></a>1. 访问 Mod 上下文对象</h2>
<div class="sectionbody">
<div class="paragraph">
<p>本指南中的所有示例都将假设一个名为ctx的 Mod 上下文对象在当前范围内。</p>
</div>
<div class="sect2">
<h3 id="_在模块中"><a class="anchor" href="#_在模块中"></a>1.1. 在模块中</h3>
<div class="paragraph">
<p>在<code>manifest.json</code>中，如果一个模块被定义为你的模组的<code>“设置”（setup）</code>，那么导出的<code>setup</code>函数将接收一个上下文对象作为唯一的参数</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">export function setup(ctx) {
  // ...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>否则，使用全局的 <code>mod.getContext</code> 方法，传入您模块的元对象：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">const ctx = mod.getContext(import.meta);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_在脚本中"><a class="anchor" href="#_在脚本中"></a>1.2. 在脚本中</h3>
<div class="paragraph">
<p>对于脚本来说，推荐的方法是使用全局的 <code>mod.register</code> 方法。这只适用于通过 <code>manifest.json</code> 的<code>“load”</code>属性或 context 对象的 <code>loadScript</code> 方法注入的脚本。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">mod.register(ctx =&gt; {
  // ...
});</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_在生命周期方法中"><a class="anchor" href="#_在生命周期方法中"></a>1.3. 在生命周期方法中</h3>
<div class="paragraph">
<p>所有游戏生命周期方法回调也将只接收到各自mod的上下文对象作为唯一参数。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">onCharacterLoaded(ctx =&gt; {
  // ...
});</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_在开发上下文中"><a class="anchor" href="#_在开发上下文中"></a>1.4. 在开发上下文中</h3>
<div class="paragraph">
<p>为了方便原型设计，您可以使用全局的 <code>mod.getDevContext</code> 方法来获取一个特殊的开发 mod 上下文对象。这不应用于 mod 中，仅用于开发目的（通过控制台）。任何需要资源的 API 都不会起作用，因为开发“mod”不包含任何资源。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">const devCtx = mod.getDevContext();</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_获取属性"><a class="anchor" href="#_获取属性"></a>2. 获取属性</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_name_string"><a class="anchor" href="#_name_string"></a>2.1. name: string</h3>
<div class="paragraph">
<p>mod的名字</p>
</div>
</div>
<div class="sect2">
<h3 id="_namespace_string_undefined"><a class="anchor" href="#_namespace_string_undefined"></a>2.2. namespace: string | undefined</h3>
<div class="paragraph">
<p>定义mod的namespace，如果提供的话</p>
</div>
</div>
<div class="sect2">
<h3 id="_version_string"><a class="anchor" href="#_version_string"></a>2.3. version: string</h3>
<div class="paragraph">
<p>当前加载的mod的版本号</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="加载资源"><a class="anchor" href="#加载资源"></a>3. 加载资源</h2>
<div class="sectionbody">
<div class="paragraph">
<p><strong>🚨所有资源文件路径必须相对于您 mod 的根目录🚨</strong></p>
</div>
<div class="sect2">
<h3 id="_getresourceurlpath_string_string"><a class="anchor" href="#_getresourceurlpath_string_string"></a>3.1. getResourceUrl(path: string): string</h3>
<div class="paragraph">
<p>获取您的 Mod 打包中的任何资源的可用 URL。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>path: string</code> 生成 URL 的资源的相对路径</p>
</div>
<div class="paragraph">
<p><strong>返回</strong></p>
</div>
<div class="paragraph">
<p><code>string</code> 请求的资源的URL</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">const url = ctx.getResourceUrl('sea-shanty-2.ogg');
const song = new Audio(url);
song.loop = true;
song.play();</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_loadmodulepath_string_promiseany"><a class="anchor" href="#_loadmodulepath_string_promiseany"></a>3.2. loadModule(path: string): Promise&lt;any&gt;</h3>
<div class="paragraph">
<p>动态导入一个JavaScript模块。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>path: string</code> 模块资源的相对路径</p>
</div>
<div class="paragraph">
<p><strong>返回</strong></p>
</div>
<div class="paragraph">
<p><code>Promise&lt;any&gt;</code> 一个 Promise，该 Promise 将解析为包含模块导出特性的对象</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">// my-module.mjs
export function greet(name) {
  console.log(`Hello, ${name}!`);
}</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">const myModule = await ctx.loadModule('my-module.mjs');
myModule.greet('Melvor'); // Hello, Melvor!</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_loadscriptpath_string_promisevoid"><a class="anchor" href="#_loadscriptpath_string_promisevoid"></a>3.3. loadScript(path: string): Promise&lt;void&gt;</h3>
<div class="paragraph">
<p>将一个JavaScript文件注入到页面中。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>path: string</code> 脚本资源的相对路径</p>
</div>
<div class="paragraph">
<p><strong>返回</strong></p>
</div>
<div class="paragraph">
<p><code>Promise&lt;void&gt;</code> 一个 Promise，当注入的脚本执行完毕时，该 Promise 将解析</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">// Await call if wanting the script to run before continuing
await ctx.loadScript('my-script.js');
// my-script.js has run

// Don't await if no dependency on script
ctx.loadScript('my-independednt-script.js');
// my-independent-script.js has NOT run yet</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_loadtemplatespath_string_promisevoid"><a class="anchor" href="#_loadtemplatespath_string_promisevoid"></a>3.4. loadTemplates(path: string): Promise&lt;void&gt;</h3>
<div class="paragraph">
<p>将给定 HTML 文件中包含的所有 <code>&lt;template&gt;</code> 元素注入到文档主体中。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>path: string</code> HTML 资源的相对路径</p>
</div>
<div class="paragraph">
<p><strong>返回</strong></p>
</div>
<div class="paragraph">
<p><code>Promise&lt;void&gt;</code> 一个在所有模板被注入到文档主体后解析的承诺。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.loadTemplates('my-templates.html');</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_loadstylesheetpath_string_void"><a class="anchor" href="#_loadstylesheetpath_string_void"></a>3.5. loadStylesheet(path: string): void</h3>
<div class="paragraph">
<p>将 CSS 样式表注入到页面中。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>path: string</code> 样式表资源的相对路径</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.loadStylesheet('my-styles.css');</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_loaddatapath_string_promiseany"><a class="anchor" href="#_loaddatapath_string_promiseany"></a>3.6. loadData(path: string): Promise&lt;any&gt;</h3>
<div class="paragraph">
<p>从 JSON 资源加载数据。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>path: string</code> JSON 资源的相对路径</p>
</div>
<div class="paragraph">
<p><strong>返回</strong></p>
</div>
<div class="paragraph">
<p><code>Promise&lt;any&gt;</code> 一个解析为 JSON 对象的承诺。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-json hljs" data-lang="json">// my-data.json
{
  "coolThings": [
    "rocks"
  ]
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><em>JSON 中的注释仅仅是示意性的，而不是有效的标记。</em></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">// in JavaScript
const myData = await ctx.loadData('my-data.json');
console.log(myData.coolThings); // ['rocks']</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_共享资源"><a class="anchor" href="#_共享资源"></a>4. 共享资源</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_shareresourcepath_string_void"><a class="anchor" href="#_shareresourcepath_string_void"></a>4.1. share(resourcePath: string): void</h3>
<div class="paragraph">
<p>共享一个打包的 Mod 资源，供其他 Mod 使用。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>resourcePath: string</code> 要共享的资源路径</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-json hljs" data-lang="json">// manifest.json
{
  "namespace": "helloMelvor"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><em>JSON 中的注释仅仅是示意性的，而不是有效的标记。</em></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">// in JavaScript
ctx.share('my_cool_image.png');
ctx.share('Greeter.mjs');</code></pre>
</div>
</div>
<div class="paragraph">
<p>然后其他的 Mod 可以在任何接受 Mod 资源路径的地方使用这个资源。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.getResourceUrl('helloMelvor:my_cool_image.png');
const { Greeter } = await loadModule('helloMelvor:Greeter.mjs');
const greeter = new Greeter();</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="生命周期钩子"><a class="anchor" href="#生命周期钩子"></a>5. 生命周期钩子</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_onmodsloadedcallback_ctx_modcontext_void_promisevoid_void"><a class="anchor" href="#_onmodsloadedcallback_ctx_modcontext_void_promisevoid_void"></a>5.1. onModsLoaded(callback: (ctx: ModContext) &#8658; void | Promise&lt;void&gt;): void</h3>
<div class="paragraph">
<p>在所有 Mod 已加载后执行代码（角色选择屏幕）。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>callback: (ctx: ModContext) &#8658; void | Promise&lt;void&gt;</code> 一个回调函数，接收 Mod 的上下文对象作为参数。可以是同步或异步的。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.onModsLoaded(async (ctx) =&gt; {
  // ...
});</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_oncharacterselectionloadedcallback_ctx_modcontext_void_promisevoid_void"><a class="anchor" href="#_oncharacterselectionloadedcallback_ctx_modcontext_void_promisevoid_void"></a>5.2. onCharacterSelectionLoaded(callback: (ctx: ModContext) &#8658; void | Promise&lt;void&gt;): void</h3>
<div class="paragraph">
<p>在角色选择屏幕完全加载后执行代码。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>callback: (ctx: ModContext) &#8658; void | Promise&lt;void&gt;</code> 一个回调函数，接收 Mod 的上下文对象作为参数。可以是同步或异步的。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong>：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.onCharacterSelectionLoaded(async (ctx) =&gt; {
  // ...
});</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_oninterfaceavailablecallback_ctx_modcontext_void_promisevoid_void"><a class="anchor" href="#_oninterfaceavailablecallback_ctx_modcontext_void_promisevoid_void"></a>5.3. onInterfaceAvailable(callback: (ctx: ModContext) &#8658; void | Promise&lt;void&gt;): void</h3>
<div class="paragraph">
<p>在角色加载之前但在游戏界面最初被注入到页面中（但尚未初始化）执行代码。主要用于添加界面元素，用于自定义技能，在onCharacterLoaded之前需要出现。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p>callback: (ctx: ModContext) &#8658; void | Promise&lt;void&gt; 一个回调函数，接收 Mod 的上下文对象作为参数。可以是同步或异步的。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.onInterfaceAvailable(async (ctx) =&gt; {
  // ...
});</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_oncharacterloadedcallback_ctx_modcontext_void_promisevoid_void"><a class="anchor" href="#_oncharacterloadedcallback_ctx_modcontext_void_promisevoid_void"></a>5.4. onCharacterLoaded(callback: (ctx: ModContext) &#8658; void | Promise&lt;void&gt;): void</h3>
<div class="paragraph">
<p>在玩家选择的角色加载并创建所有游戏对象后，但在离线进度计算之前执行代码。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>callback: (ctx: ModContext) &#8658; void | Promise&lt;void&gt;</code> 一个回调函数，接收 Mod 的上下文对象作为参数。可以是同步或异步的。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.onCharacterLoaded(async (ctx) =&gt; {
  // ...
});</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_oninterfacereadycallback_ctx_modcontext_void_promisevoid_void"><a class="anchor" href="#_oninterfacereadycallback_ctx_modcontext_void_promisevoid_void"></a>5.5. onInterfaceReady(callback: (ctx: ModContext) &#8658; void | Promise&lt;void&gt;): void</h3>
<div class="paragraph">
<p>在离线进度被计算后，所有游戏内用户界面元素都被创建后执行代码。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>callback: (ctx: ModContext) &#8658; void | Promise&lt;void&gt;</code> 一个回调函数，接收 Mod 的上下文对象作为参数。可以是同步或异步的。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.onInterfaceReady(async (ctx) =&gt; {
  // ...
});</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="注册游戏对象"><a class="anchor" href="#注册游戏对象"></a>6. 注册游戏对象</h2>
<div class="sectionbody">
<div class="paragraph">
<p>游戏对象注册 API 可以通过根上下文对象的 <code>gameData</code> 属性来访问。</p>
</div>
<div class="sect2">
<h3 id="_addpackagedata_string_gamedatapackage_promisevoid"><a class="anchor" href="#_addpackagedata_string_gamedatapackage_promisevoid"></a>6.1. addPackage(data: string | GameDataPackage): Promise&lt;void&gt;</h3>
<div class="paragraph">
<p>注册一个游戏数据包。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>data: string | GameDataPackage</code> 资源路径到您的游戏数据包 <code>.json</code> 文件或者有效的 JavaScript GameDataPackage 对象。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-json hljs" data-lang="json">// data.json
{
  "$schema": "https://melvoridle.com/assets/schema/gameData.json",
  "data": {
    // data objects here
  }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><em>JSON 中的注释仅仅是示意性的，而不是有效的标记。</em></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">await ctx.gameData.addPackage('data.json');</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_buildpackagebuilder_packagebuilder_gamedatapackagebuilder_void_builtgamedatapackage"><a class="anchor" href="#_buildpackagebuilder_packagebuilder_gamedatapackagebuilder_void_builtgamedatapackage"></a>6.2. buildPackage(builder: (packageBuilder: GameDataPackageBuilder) &#8658; void): BuiltGameDataPackage</h3>
<div class="paragraph">
<p>使用 <code>GameDataPackageBuilder</code> API 构建一个 GameDataPackage 对象。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>builder: (packageBuilder: GameDataPackageBuilder) &#8658; void</code> 用于向数据包添加单个游戏对象的构建器。</p>
</div>
<div class="paragraph">
<p><strong>返回</strong></p>
</div>
<div class="paragraph">
<p><code>BuiltGameDataPackage</code> 游戏数据包的包装器。请参阅下面的信息。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.gameData.buildPackage((p) =&gt; {
  // data registration here
});</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="_builtgamedatapackage_package_gamedatapackage"><a class="anchor" href="#_builtgamedatapackage_package_gamedatapackage"></a>6.2.1. BuiltGameDataPackage.package: GameDataPackage</h4>
<div class="paragraph">
<p>（Property）实际构建的 <code>GameDataPackage</code> 对象。</p>
</div>
</div>
<div class="sect3">
<h4 id="_builtgamedatapackage_add_void"><a class="anchor" href="#_builtgamedatapackage_add_void"></a>6.2.2. BuiltGameDataPackage.add(): void</h4>
<div class="paragraph">
<p>注册已构建的游戏数据包。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">const pkg = ctx.gameData.buildPackage((p) =&gt; { /* ... */ });
pkg.add();</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="Mod配置"><a class="anchor" href="#Mod配置"></a>7. Mod配置</h2>
<div class="sectionbody">
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
当通过 Creator Toolkit 将您的 Mod 作为本地 Mod 加载时，您的 Mod 必须与 mod.io 进行关联，并且您必须通过 mod.io 订阅并安装了该 Mod，以便使这些数据持久化。
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Mod 设置 API 可以通过根上下文对象上的 <code>settings</code> 属性来访问。</p>
</div>
<div class="sect2">
<h3 id="_sectionname_string_section"><a class="anchor" href="#_sectionname_string_section"></a>7.1. section(name: string): Section</h3>
<div class="paragraph">
<p>获取或创建一个设置部分。部分创建的顺序决定了它们在 Mod 设置窗口中的显示顺序。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>name: string</code> 部分的名称。这将显示为设置窗口中的部分标题。</p>
</div>
<div class="paragraph">
<p><strong>返回</strong></p>
</div>
<div class="paragraph">
<p><code>Section</code> 部分的对象，用于执行添加、设置或获取设置。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.settings.section('General');
ctx.settings.section('Other');
// Sections will be displayed in the settings window in this order
// 1. General
// 2. Other</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="_section_addconfig_settingconfig_settingconfig_void"><a class="anchor" href="#_section_addconfig_settingconfig_settingconfig_void"></a>7.1.1. Section.add(config: SettingConfig | SettingConfig[]): void</h4>
<div class="paragraph">
<p>向部分添加设置。设置添加到部分的顺序决定了它们在 Mod 设置窗口中的显示顺序。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>config: SettingConfig | SettingConfig[]</code> 设置的配置对象或配置对象数组，以一次添加多个设置。请参阅下面的“设置类型”部分以获取设置配置选项。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.settings.section('General').add({
  type: 'switch',
  name: 'awesomeness-detection',
  label: 'Awesomeness Detection',
  hint: 'Determines if you are awesome or not.',
  default: false
});

ctx.settings.section('Other').add([{
    type: 'label',
    label: 'I am just a label though my story seldom told...'
  }, {
    type: 'number',
    name: 'pick-a-number',
    label: 'Pick a Number',
    hint: '1 through 10'
}]);</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_section_getname_string_any"><a class="anchor" href="#_section_getname_string_any"></a>7.1.2. Section.get(name: string): any</h4>
<div class="paragraph">
<p>通过其名称属性获取设置的当前值。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>name: string</code> 要获取值的设置的名称</p>
</div>
<div class="paragraph">
<p><strong>返回</strong></p>
</div>
<div class="paragraph">
<p><code>any</code> 设置的当前值</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">// Assuming the player has typed "1" into the setting
ctx.settings.section('Other').get('pick-a-number'); // 1</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_section_setname_string_value_any_void"><a class="anchor" href="#_section_setname_string_value_any_void"></a>7.1.3. Section.set(name: string, value: any): void</h4>
<div class="paragraph">
<p>通过其名称属性以编程方式设置设置的值。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>name: string</code> 要设置值的设置的名称</p>
</div>
<div class="paragraph">
<p><code>value: any</code> 要设置的值</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.settings.section('Other').set('pick-a-number', 5);</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_typename_string_config_settingtypeconfig_void"><a class="anchor" href="#_typename_string_config_settingtypeconfig_void"></a>7.2. type(name: string, config: SettingTypeConfig): void</h3>
<div class="paragraph">
<p>注册一个设置类型，然后可以在添加设置时由任何 Mod 使用。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>name: string</code> 设置类型的名称。这是在添加新设置时用于设置配置的类型属性。其他 Mod 必须在名称前加上您的 Mod 命名空间。</p>
</div>
<div class="paragraph">
<p><code>config: SettingTypeConfig</code> 定义设置类型行为的对象。请参见下面的定义。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-json hljs" data-lang="json">// manifest.json
{
  "namespace": "my_mod"
  // ...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><em>JSON 中的注释仅仅是示意性的，而不是有效的标记。</em></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.settings.type('customText', {
  // See example config in SettingTypeConfig section below
});

ctx.settings.section('General').add({
  type: 'customText',
  // ...
});</code></pre>
</div>
</div>
<div class="paragraph">
<p>其他 Mod 必须添加您的命名空间以使用您的自定义类型：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.settings.section('Other').add({
  type: 'my_mod:customText',
  // ...
});</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="_settingtypeconfig"><a class="anchor" href="#_settingtypeconfig"></a>7.2.1. SettingTypeConfig</h4>
<div class="paragraph">
<p>所有函数都是必需的。</p>
</div>
<div class="sect4">
<h5 id="_rendername_string_onchange_void_config_settingconfig_htmlelement"><a class="anchor" href="#_rendername_string_onchange_void_config_settingconfig_htmlelement"></a>render(name: string, onChange: () &#8658; void, config: SettingConfig): HTMLElement</h5>
<div class="paragraph">
<p>render 函数负责使用传递给配置的属性来渲染设置的 HTML。</p>
</div>
<div class="paragraph">
<p><code>name</code> 参数可在必要时用作设置的 HTML 中的 id。常见用例是将 <code>&lt;input&gt;</code> 的 <code>name</code> 和 <code>id</code> 属性设置为此值，然后将 <code>&lt;label&gt;</code> 的 <code>for</code> 属性也设置为此值。</p>
</div>
<div class="paragraph">
<p><code>onChange</code> 参数应在更改此设置的值时调用。常见用例是将其添加为 <code>&lt;input&gt;</code> 元素的 <code>change</code> 事件的事件监听器。</p>
</div>
<div class="paragraph">
<p><code>config</code> 参数包含在添加此设置时传递给配置对象的所有值。例如，<code>label</code>，<code>hint</code>，<code>default</code>等属性。</p>
</div>
<div class="paragraph">
<p>个别设置可以选择在其 <code>onChange</code> 方法中返回验证错误。您可以在具有 <code>validation-message</code> 类的元素中显示此验证错误的位置。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">// The render function for a simple text box
function render(name, onChange, config) {
  const input = document.createElement('input');
  input.id = name;
  input.type = 'text';
  input.name = name;
  input.addEventListener('change', () =&gt; onChange());

  const label = document.createElement('label');
  label.for = name;
  label.textContent = config.label;

  if (config.hint) {
    const hint = document.createElement('small');
    hint.textContent = config.hint;
    label.appendChild(hint);
  }

  const validation = document.createElement('small');
  validation.classList.add('text-danger', 'validation-message');

  const root = document.createElement('div');
  root.appendChild(input);
  root.appendChild(label);
  root.appendChild(validation);

  return root;
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_getroot_htmlelement_any"><a class="anchor" href="#_getroot_htmlelement_any"></a>get(root: HTMLElement): any</h5>
<div class="paragraph">
<p><code>get</code> 函数负责检索设置的当前值。它只接收一个参数，即从 render 函数返回的根 HTML 元素，这对于获取当前值可能会有用。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">// get function for simple text input defined by above render
function get(root) {
  return root.querySelector('input').value;
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_setroot_htmlelement_value_any_void"><a class="anchor" href="#_setroot_htmlelement_value_any_void"></a>set(root: HTMLElement, value: any): void</h5>
<div class="paragraph">
<p><code>set</code> 函数负责将 HTML 与当前值保持同步（如果以编程方式更新）。它接收来自 render 函数的根 HTML 元素和要设置的值作为两个参数。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">// set function for simple text setting defined above
function set(root, value) {
  root.querySelector('input').value = value;
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_示例"><a class="anchor" href="#_示例"></a>7.2.2. 示例</h4>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">// Use functions defined in above examples as reference
ctx.settings.type('simpleText', {
  render: render,
  get: get,
  set: set
});</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_内置类型"><a class="anchor" href="#_内置类型"></a>7.3. 内置类型</h3>
<div class="sect3">
<h4 id="_基本设置配置"><a class="anchor" href="#_基本设置配置"></a>7.3.1. 基本设置配置</h4>
<div class="paragraph">
<p>所有单独的设置都继承这个基本设置配置对象。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">interface SettingConfig {
  type: string; // Type of the setting
  name: string; // Name of the setting
  label: string | HTMLElement; // Display label for the setting
  hint: string | HTMLElement; // Small help text to display alongside the setting
  default: any; // Default value for the setting
  onChange(value: any, previousValue: any): void | boolean | string // See notes
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>onChange</code> 选项是一个回调函数，它接收正在设置的新值和设置的先前值。这个函数可以选择返回一个值作为验证器：</p>
</div>
<div class="ulist">
<ul>
<li>
<p>无返回值 / <code>undefined ` / `true</code> / 非字符串的真值（non-string）：验证成功，允许更改值。</p>
</li>
<li>
<p><code>false</code> / 假值：验证失败，设置的值还原到以前的值。</p>
</li>
<li>
<p><code>string </code>值：验证失败，设置的值还原到以前的值，并且字符串内容显示在 <code>.validation-message</code> 元素中，如果可用（参见上面的自定义渲染）。</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_text"><a class="anchor" href="#_text"></a>7.3.2. Text</h4>
<div class="paragraph">
<p>一个默认情况下接受任何字符的简单文本框。值的类型是<code>string</code>。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">interface TextConfig implements SettingConfig {
  type: 'text';
  maxLength: number; // Max length attribute for the textbox
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_number"><a class="anchor" href="#_number"></a>7.3.3. Number</h4>
<div class="paragraph">
<p>一个仅接受数字的简单文本框。值的类型是<code>number</code>。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">interface NumberConfig implements SettingConfig {
  type: 'number';
  min: number; // Minimum value to be entered
  max: number; // Maximum value to be entered
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_switch"><a class="anchor" href="#_switch"></a>7.3.4. Switch</h4>
<div class="paragraph">
<p>一个打开/关闭切换开关。值的类型是<code>boolean</code>。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">interface SwitchConfig implements SettingConfig {
  type: 'switch'
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_dropdown"><a class="anchor" href="#_dropdown"></a>7.3.5. Dropdown</h4>
<div class="paragraph">
<p>一个下拉按钮。例如："默认加载页面" 游戏设置。值的类型是<code>any</code>。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">DropdownConfig implements SettingConfig {
  type: 'dropdown';
  color: string; // see Button config
  options: DropdownOption[]; // see note
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>options</code> 选项定义了可供选择的下拉选项。下拉选项的结构如下：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">interface DropdownOption {
  value: any; // value that is used by the setting
  display: string | HTMLElement; // display text or element on the option
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_button"><a class="anchor" href="#_button"></a>7.3.6. Button</h4>
<div class="paragraph">
<p>一个按钮。值是<code>undefined</code>的。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">interface ButtonConfig implements SettingConfig {
  type: 'button';
  display: string | HTMLElement; // displayed text or element inside the button
  color: string; // see note
  onClick(): void; // triggered on click of the button
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>color</code> 选项附加到以 <code>btn-</code> 开头的 CSS 类，如果未定义，则默认为<code>primary </code>颜色（<code>btn-primary</code>）。可用的默认颜色有：</p>
</div>
<div class="ulist">
<ul>
<li>
<p>primary: 蓝色</p>
</li>
<li>
<p>secondary: 灰色</p>
</li>
<li>
<p>success: 绿色</p>
</li>
<li>
<p>info: 浅蓝色</p>
</li>
<li>
<p>warning: 黄色</p>
</li>
<li>
<p>danger: 红色</p>
</li>
<li>
<p>dark: 深灰色</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_checkbox_group"><a class="anchor" href="#_checkbox_group"></a>7.3.7. Checkbox Group</h4>
<div class="paragraph">
<p>一组复选框。值的类型是任何<code>any[]</code>。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">interface CheckboxGroupConfig implements SettingConfig {
  type: 'checkbox-group';
  options: CheckboxOption[]; // see note
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>options</code> 选项定义了可供选择的复选框。复选框选项的结构如下：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">interface CheckboxOption {
  value: any; // value to be added to array that is set as setting value
  label: string | HTMLElement;
  hint: string | HTMLElement;
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_radio_group"><a class="anchor" href="#_radio_group"></a>7.3.8. Radio Group</h4>
<div class="paragraph">
<p>一组单选按钮。值的类型是<code>any</code>。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">interface RadioGroupConfig implements SettingConfig {
  type: 'radio-group';
  options: CheckboxOption[]; // see checkbox group's options schema
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_label"><a class="anchor" href="#_label"></a>7.3.9. Label</h4>
<div class="paragraph">
<p>一个简单的标签。值是<code>undefined</code>的。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">interface LabelConfig implements SettingConfig {
  type: 'label';
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_自定义"><a class="anchor" href="#_自定义"></a>7.3.10. 自定义</h4>
<div class="paragraph">
<p>自定义渲染的设置。请参阅上面的 <a href="#_settingtypeconfig">SettingTypeConfig</a> 部分。这与注册自定义设置类型不同，因为这是一次性的，不会注册用于重复使用的类型。值的类型是<code>any</code>。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">interface CustomConfig implements SettingConfig, SettingTypeConfig {
  type: 'custom';
}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="存储角色数据"><a class="anchor" href="#存储角色数据"></a>8. 存储角色数据</h2>
<div class="sectionbody">
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
当通过 Creator Toolkit 将您的 Mod 作为本地 Mod 加载时，您的 Mod 必须与 mod.io 进行关联，并且您必须通过 mod.io 订阅并安装了该 Mod，以便使这些数据持久化。
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>角色存储 API 可以通过根上下文对象上的 <code>characterStorage</code> 属性来访问。</p>
</div>
<div class="sect2">
<h3 id="_限制"><a class="anchor" href="#_限制"></a>8.1. 限制</h3>
<div class="paragraph">
<p>角色存储只能在加载角色后使用（在生命周期钩子 <code>onCharacterLoaded</code> 之后）。</p>
</div>
<div class="paragraph">
<p>每个角色可以为每个 Mod 存储多达 8,192 字节（8KB）的数据，包括键。只能存储可 JSON 序列化的数据。这包括原始类型（<code>string</code>、<code>number</code>、<code>boolean</code>）以及只包含原始类型或其他符合这一描述的对象和数组的对象和数组。这种序列化/反序列化是自动处理的。</p>
</div>
</div>
<div class="sect2">
<h3 id="_setitemkey_string_data_any_void"><a class="anchor" href="#_setitemkey_string_data_any_void"></a>8.2. setItem(key: string, data: any): void</h3>
<div class="paragraph">
<p>在角色存储中设置键/值对。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>key: string</code> 用于标识正在存储的数据的键。在调用 <code>getItem</code> 和 <code>removeItem</code> 时使用。</p>
</div>
<div class="paragraph">
<p><code>data: any</code> 数据要存储。请参见上面的限制。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.characterStorage.setItem('coolThings', ['rocks']);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_getitemkey_string_any"><a class="anchor" href="#_getitemkey_string_any"></a>8.3. getItem(key: string): any</h3>
<div class="paragraph">
<p>从角色存储中根据键获取值。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>key: string</code> 要检索的数据的键</p>
</div>
<div class="paragraph">
<p><strong>返回</strong></p>
</div>
<div class="paragraph">
<p><code>any</code> 数据检索的结果。如果没有存储这样的键，则返回 <code>undefined</code>。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.characterStorage.getItem('coolThings'); // returns ['rocks']</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_removeitemkey_string_void"><a class="anchor" href="#_removeitemkey_string_void"></a>8.4. removeItem(key: string): void</h3>
<div class="paragraph">
<p>通过键从角色存储中移除键/值对。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>key: string</code> 要移除的键/值对的键。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.characterStorage.removeItem('coolThings');
ctx.characterStorage.getItem('coolThings'); // returns undefined</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_clear_void"><a class="anchor" href="#_clear_void"></a>8.5. clear(): void</h3>
<div class="paragraph">
<p>从角色存储中移除所有键/值对。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.characterStorage.clear();</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="存储账号数据"><a class="anchor" href="#存储账号数据"></a>9. 存储账号数据</h2>
<div class="sectionbody">
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
当通过 Creator Toolkit 将您的 Mod 作为本地 Mod 加载时，您的 Mod 必须与 mod.io 进行关联，并且您必须通过 mod.io 订阅并安装了该 Mod，以便使这些数据持久化。
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>帐户存储 API 可以通过根上下文对象上的 <code>accountStorage</code> 属性来访问。</p>
</div>
<div class="sect2">
<h3 id="_限制_2"><a class="anchor" href="#_限制_2"></a>9.1. 限制</h3>
<div class="paragraph">
<p>由于帐户数据的存储方式是基于云的，以及玩家可能遇到的潜在网络问题，帐户存储的数据完整性不能 100% 保证。建议谨慎使用帐户存储。</p>
</div>
<div class="paragraph">
<p>每个帐户可以为每个 Mod 存储多达 8,192 字节（8KB）的数据，包括键。只能存储可 JSON 序列化的数据。这包括原始类型（<code>string</code>、<code>number</code>、<code>boolean</code>）以及只包含原始类型或其他符合这一描述的对象和数组的对象和数组。这种序列化/反序列化是自动处理的。</p>
</div>
</div>
<div class="sect2">
<h3 id="_setitemkey_string_data_any_void_2"><a class="anchor" href="#_setitemkey_string_data_any_void_2"></a>9.2. setItem(key: string, data: any): void</h3>
<div class="paragraph">
<p>在帐户存储中设置键/值对。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>key: string</code> 用于标识正在存储的数据的键。在调用 <code>getItem</code> 和 <code>removeItem</code> 时使用。</p>
</div>
<div class="paragraph">
<p><code>data: any</code> 数据要存储。请参见上面的限制。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.accountStorage.setItem('coolThings', ['rocks']);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_getitemkey_string_any_2"><a class="anchor" href="#_getitemkey_string_any_2"></a>9.3. getItem(key: string): any</h3>
<div class="paragraph">
<p>从帐户存储中根据键获取值。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>key: string</code> 要检索的数据的键</p>
</div>
<div class="paragraph">
<p><strong>返回</strong></p>
</div>
<div class="paragraph">
<p><code>any</code> 数据检索的结果。如果没有存储这样的键，则返回 <code>undefined</code>。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.accountStorage.getItem('coolThings'); // returns ['rocks']</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_removeitemkey_string_void_2"><a class="anchor" href="#_removeitemkey_string_void_2"></a>9.4. removeItem(key: string): void</h3>
<div class="paragraph">
<p>通过键从帐户存储中移除键/值对。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>key: string</code> 要移除的键/值对的键。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.accountStorage.removeItem('coolThings');
ctx.accountStorage.getItem('coolThings'); // returns undefined</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_clear_void_2"><a class="anchor" href="#_clear_void_2"></a>9.5. clear(): void</h3>
<div class="paragraph">
<p>从帐户存储中移除所有键/值对。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.accountStorage.clear();</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="游戏对象修补-钩子"><a class="anchor" href="#游戏对象修补-钩子"></a>10. 游戏对象补丁/钩子</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_patchclassname_class_methodorpropertyname_string_methodpatch_propertypatch"><a class="anchor" href="#_patchclassname_class_methodorpropertyname_string_methodpatch_propertypatch"></a>10.1. patch(className: class, methodOrPropertyName: string): MethodPatch | PropertyPatch</h3>
<div class="paragraph">
<p>这是方法和 getter/setter 补丁 API 的入口点。根据第二个参数是方法还是 getter/setter 属性，将分别返回 <code>MethodPatch</code> 或 <code>PropertyPatch</code> 对象。然后应使用 MethodPatch/PropertyPatch 对象来执行指定类和方法/属性的进一步操作。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>className: class</code> 包含要补丁的方法或 getter/setter 的类。应该是实际的类引用，而不是字符串，例如，<code>Skill</code>，而不是<code>'Skill'</code>。</p>
</div>
<div class="paragraph">
<p><code>methodOrPropertyName: string</code> 要补丁的方法或 getter/setter 属性的名称。</p>
</div>
<div class="paragraph">
<p><strong>返回</strong></p>
</div>
<div class="paragraph">
<p><code>MethodPatch | PropertyPatcch</code> 指定类和方法或 getter/setter 属性的补丁对象。请参阅下面的用法。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.patch(Skill, 'addXP'); // Returns a MethodPatch
ctx.patch(Skill, 'level'); // Returns a PropertyPatch</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="_methodpatch_beforehook_args_any_any_void_void"><a class="anchor" href="#_methodpatch_beforehook_args_any_any_void_void"></a>10.1.1. MethodPatch.before(hook: (&#8230;&#8203;args: any) &#8658; any[] | void): void</h4>
<div class="paragraph">
<p>在方法体调用之前立即执行回调函数。回调函数的参数是传递给方法调用的参数。可选地，回调函数可以返回一个值数组，以覆盖传递给方法体的参数。如果没有指定返回值（返回 <code>undefined</code>），参数将保持不变。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>hook: (&#8230;&#8203;args: any) &#8658; any[] | void</code> 要执行的回调钩子。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">// Double all XP gains
ctx.patch(Skill, 'addXP').before((amount, masteryAction) =&gt; [amount * 2, masteryAction]);</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_methodpatch_afterhook_returnvalue_any_args_any_any_void_void"><a class="anchor" href="#_methodpatch_afterhook_returnvalue_any_args_any_any_void_void"></a>10.1.2. MethodPatch.after(hook: (returnValue: any, &#8230;&#8203;args: any) &#8658; any | void): void</h4>
<div class="paragraph">
<p>在方法体执行完毕后立即执行回调函数。回调函数的第一个参数是方法体返回的值。其余的参数是传递给方法体的参数。可选地，回调函数可以返回一个新值以覆盖方法的返回值。如果没有指定返回值（返回 <code>undefined</code>），则返回值将保持不变。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>hook: (returnValue: any, &#8230;&#8203;args: any) &#8658; any | void</code> 要执行的回调钩子。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">// The player never misses an attack
ctx.patch(Player, 'rollToHit').after(willHit =&gt; {
  if (!willHit) console.log('A miss? I think not!');
  return true;
});</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_methodpatch_replacereplacement_replacedmethod_args_any_any_args_any_any_void"><a class="anchor" href="#_methodpatch_replacereplacement_replacedmethod_args_any_any_args_any_any_void"></a>10.1.3. MethodPatch.replace(replacement: (replacedMethod: (&#8230;&#8203;args: any) &#8658; any, &#8230;&#8203;args: any) &#8658; any): void</h4>
<div class="paragraph">
<p>执行一个回调函数来代替方法的当前体。回调函数的第一个参数是被替换的方法体。其余的参数是应该传递给方法的参数。回调函数的返回值是方法的返回值。替代函数仍然受到在 <code>before</code> 和 <code>after</code> 钩子中对参数/返回值的修改的影响。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>replacement: (replacedMethod: (&#8230;&#8203;args: any) &#8658; any, &#8230;&#8203;args: any) &#8658; any</code> 用于替代方法体的回调函数。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.patch(Skill, 'addXP').replace(function(o, amount, masteryAction) {
  // Prevent any woodcutting XP
  if (this.id === 'melvorD:Woodcutting') return;

  // Double any mining XP
  if (this.id === 'melvorD:Mining') return o(amount * 2, masteryAction);

  // Grant all other XP as normal
  return o(amount, masteryAction);
});</code></pre>
</div>
</div>
<div class="paragraph">
<p>值得注意的是，使用 <code>replace</code> 方法会替换当前的方法体，这意味着多次调用 <code>replace</code> 方法的执行顺序与它们声明的顺序相反：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">const xpPatch = ctx.patch(Skill, 'addXP');

xpPatch.replace((o, amount, masteryAction) =&gt; {
  console.log('Replacement #1');
  return o(amount, masteryAction);
});

xpPatch.replace({o, amount, masteryAction) =&gt; {
  console.log('Replacement #2');
  return o(amount, masteryAction);
});

game.woodcutting.addXP(100);
// Logs:
// Replacement #2
// Replacement #1</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_propertypatch_getgetter_o_any_any_void"><a class="anchor" href="#_propertypatch_getgetter_o_any_any_void"></a>10.1.4. PropertyPatch.get(getter: (o: () &#8658; any) &#8658; any): void</h4>
<div class="paragraph">
<p>在访问 getter 属性时执行提供的函数并返回返回值。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>getter: (o: () &#8658; any) &#8658; any</code> 要执行的 getter 函数。参数 <code>o</code> 是一个引用，指向被替换的 getter 方法，它可以是以前的 getter 补丁或原始的 getter 方法。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">// Effectively double available Township resources
ctx.patch(TownshipResource, 'amount').get((o) =&gt; o() * 2);
// Or more practically, make resources unlimited
ctx.patch(TownshipResource, 'amount').get(() =&gt; 999999);</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_propertypatch_setsetter_o_value_any_void_value_any_void_void"><a class="anchor" href="#_propertypatch_setsetter_o_value_any_void_value_any_void_void"></a>10.1.5. PropertyPatch.set(setter: (o: (value: any) &#8658; void, value: any) &#8658; void): void</h4>
<div class="paragraph">
<p>在访问 setter 属性时执行提供的函数。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>setter: (o: (value: any) &#8658; void, value: any) &#8658; void</code> 要执行的 setter 函数。第一个参数 <code>o</code> 是一个引用，指向被替换的 setter 方法，它可以是以前的 setter 补丁或原始的 setter 方法。第二个参数 <code>value</code> 包含被设置的值。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">// Sorry, there aren't many setters in the game to use for a practical example
// Doubles whatever resource amount is being set
ctx.patch(TownshipResource, 'amount').set((o, amount) =&gt; o(amount * 2));
// While in-game
game.township.resources.getObjectByID('melvorF:Wood').amount = 1000;
game.township.renderQueue.resourceAmounts = true;
// 2000 wood is available</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_propertypatch_replacegetter_o_any_any_setter_o_value_any_void_value_any_void_void"><a class="anchor" href="#_propertypatch_replacegetter_o_any_any_setter_o_value_any_void_value_any_void_void"></a>10.1.6. PropertyPatch.replace(getter?: (o: () &#8658; any) &#8658; any, setter?: (o: (value: any) &#8658; void, value: any) &#8658; void): void</h4>
<div class="paragraph">
<p>同时调用 <code>get</code> 和 <code>set</code> 的别名。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>getter: (o: () &#8658; any) &#8658; any</code> 参见上面的 <code>get</code> 参数。</p>
</div>
<div class="paragraph">
<p><code>setter: (o: (value: any) &#8658; void, value: any) &#8658; void</code> 参见上面的 <code>set</code> 参数。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="paragraph">
<p>请参见上面的 <code>get</code> 和 <code>set</code> 示例。</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_ispatchedclassname_class_methodorpropertyname_string_boolean"><a class="anchor" href="#_ispatchedclassname_class_methodorpropertyname_string_boolean"></a>10.2. isPatched(className: class, methodOrPropertyName: string): boolean</h3>
<div class="paragraph">
<p>检查方法或 getter/setter 属性是否已经被打补丁。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>className: class</code> 包含要检查是否已经被打补丁的方法或属性的类。应该是实际的类引用，而不是字符串，例如，<code>Skill</code>，而不是<code>'Skill'</code>。</p>
</div>
<div class="paragraph">
<p><code>methodOrPropertyName: string</code> 要检查的方法或属性的名称。</p>
</div>
<div class="paragraph">
<p><strong>返回</strong></p>
</div>
<div class="paragraph">
<p><code>boolean</code> 给定的类方法或属性是否已经被打补丁。</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">ctx.isPatched(Skill, 'addXP'); // false
ctx.patch(Skill, 'addXP');
ctx.isPatched(Skill, 'addXP'); // true</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="公开属性与方法"><a class="anchor" href="#公开属性与方法"></a>11. 公开属性与方法</h2>
<div class="sectionbody">
<div class="paragraph">
<p>您可能希望允许其他 Mod 通过您定义的 API 与您的 Mod 进行交互或集成。为此，推荐的方法是使用上下文对象上的 <code>api</code> 方法。通过以下方法定义 API 后，其他 Mod 可以通过全局的 <code>mod.api['your_mods_namespace']</code> 对象访问它。</p>
</div>
<div class="sect2">
<h3 id="_apiendpoints_object_object"><a class="anchor" href="#_apiendpoints_object_object"></a>11.1. api(endpoints?: object): object</h3>
<div class="paragraph">
<p>指定要在全局 <code>mod.api['your_mods_namespace']</code> 对象上公开的属性和方法。可以多次调用以添加更多端点。</p>
</div>
<div class="paragraph">
<p><strong>参数</strong></p>
</div>
<div class="paragraph">
<p><code>endpoint: object</code> 包含您要公开的任何属性或方法的对象。如果省略，将只检索您的 Mod 的当前 API 对象。</p>
</div>
<div class="paragraph">
<p><strong>返回</strong></p>
</div>
<div class="paragraph">
<p><code>object</code> Mod 的 API 对象</p>
</div>
<div class="paragraph">
<p><strong>示例</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">// manifest.json
{
  "namespace": "helloWorld",
  "setup": "setup.mjs"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><em>JSON 中的注释仅用于示意，不是有效的标记。</em></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">// setup.mjs
export function setup({ api }) {
  api({
    greet: name =&gt; console.log(`Hello, ${name!}`);
  });
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>然后，其他 Mod 将能够与您的 API 进行交互：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">// some other mod
mod.api.helloWorld.greet('Melvor'); // Hello, Melvor!</code></pre>
</div>
</div>
<table class="tableblock frame-all grid-all fit-content">
<colgroup>
<col>
<col>
<col>
<col>
<col>
<col>
<col>
<col>
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-center valign-middle" colspan="8"><p class="tableblock"><strong>Mod指南</strong></p></td>
</tr>
<tr>
<td class="tableblock halign-center valign-middle"><p class="tableblock"><a href="入门指南.html" class="xref page">Mod开发的入门指南</a></p></td>
<td class="tableblock halign-center valign-middle"><p class="tableblock"><a href="创作工具包.html" class="xref page">创作工具包</a></p></td>
<td class="tableblock halign-center valign-middle"><p class="tableblock"><a href="从脚本和扩展迁移.html" class="xref page">从脚本和扩展迁移</a></p></td>
<td class="tableblock halign-center valign-middle"><p class="tableblock"><a href="基础指南.html" class="xref page">基础指南</a></p></td>
<td class="tableblock halign-center valign-middle"><p class="tableblock"><a href="Mod上下文API参考.html" class="xref page">Mod上下文API参考</a></p></td>
<td class="tableblock halign-center valign-middle"><p class="tableblock"><a href="侧边栏API参考.html" class="xref page">侧边栏API参考</a></p></td>
<td class="tableblock halign-center valign-middle"><p class="tableblock"><a href="使用PetiteVue创建可复用组件.html" class="xref page">使用PetiteVue创建可复用组件</a></p></td>
<td class="tableblock halign-center valign-middle"><p class="tableblock"><a href="启用Steam客户端的DevTools.html" class="xref page">启用Steam客户端的DevTools</a></p></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</article>
  </div>
</main>
</div>
<script id="site-script" src="../../../_/js/site.js" data-ui-root-path="../../../_"></script>
<script async src="../../../_/js/vendor/highlight.js"></script>

  </body>
</html>
